Empowering Trauma and EMS QI Processes

{traumar} and {nemsqar}

Nicolas Foss, Ed.D., MS

2025-08-10

QI Matters to Trauma and EMS Programs

  • EMS and trauma systems critically depend on timely, accurate performance data
  • Most U.S. jurisdictions require reporting to a centralized trauma registry and EMS registry
  • Each hospital and EMS service have access to their own raw data via their Electronic Health Record (EHR)
  • Hospitals and EMS services often lack infrastructure for data science and/or staff
  • EHRs and National repositories for EMS/trauma data provide limited supports for performance calculation

Overview: National Context

  • National Trauma Data Bank: trauma registry data, hospital-based
  • National EMS Information System: national EMS data, prehospital events
  • NTDB and NEMSIS: Consistent element names for respective registry types, standardized formats
  • National EMS Quality Alliance: National EMS Quality Alliance, expert EMS stakeholders, published 21 EMS service quality measures
  • SEQIC: System Evaluation and Quality Improvement Committee, Iowa-based, designed 13 trauma system quality measures

Introducing traumar

  • Implements metrics driven the by academic literature
    • Risk-adjusted mortality metrics
      • W, M, and Z scores (Based on the Major Trauma Outcomes Study)
      • Relative mortality metric (RMM) from Napoli et a. (2017)
  • Built to calculate SEQIC indicators
  • Friendly to NTDB data formats and others

traumar: Examples!

Here, we will explore traumar::seqic_indicator_1()

Example Trauma Data

# Set a random number seed
set.seed(10232015)

# Some useful synthetic data
  valid_data <- tibble::tibble(
  incident_id = 1:100,
  activation_level = factor(
    sample(c("Level 1", "Level 2", "None"), 
           size = 100, 
           replace = TRUE, 
           prob = c(0.8, 0.1, 0.1)
           )
    ),
  provider_type = factor(
    sample(c("Surgery/Trauma", "Emergency Medicine"), 
           size = 100, 
           replace = TRUE
           )
    ),
  trauma_level = factor(
    sample(c("I", "II", "III", "IV"), 
           size = 100, 
           replace = TRUE, 
           prob = c(0.3, 0.3, 0.2, 0.2)
           )
    ),
  response_minutes = rnorm(100, mean = 8, sd = 5),
  provider = sample(c("Dr. A", "Dr. B", "Dr. C", "Dr. D"), 
                    size = 100, 
                    replace = TRUE
                    )
)

Example Trauma Data

# Check out the data
dplyr::glimpse(valid_data)
Rows: 100
Columns: 6
$ incident_id      <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
$ activation_level <fct> Level 2, None, Level 1, Level 1, Level 1, Level 1, No…
$ provider_type    <fct> Surgery/Trauma, Surgery/Trauma, Surgery/Trauma, Emerg…
$ trauma_level     <fct> I, IV, I, I, III, II, IV, III, IV, I, II, I, I, I, I,…
$ response_minutes <dbl> 17.7593522, 1.8275233, 5.0991700, 6.2669883, 9.092127…
$ provider         <chr> "Dr. A", "Dr. A", "Dr. B", "Dr. A", "Dr. C", "Dr. C",…

Run the Function

Group the output by verification level and calculate 95% confidence intervals

indicator_1 <- valid_data |> 
  traumar::seqic_indicator_1(
  trauma_team_activation_level = activation_level,
  trauma_team_physician_service_type = provider_type,
  level = trauma_level,
  included_levels = c("I", "II", "III", "IV"),
  unique_incident_id = incident_id,
  response_time = response_minutes,
  trauma_team_activation_provider = provider,
  groups = "trauma_level",
  calculate_ci = "wilson"
) |> 
  dplyr::select(trauma_level, tidyselect::matches("(?:seqic_|ci_)1[ad]"))

Results

The output 1!

indicator_1 |> 
  dplyr::mutate(
    dplyr::across(-1, 
                  ~ ifelse(!is.na(.), 
      traumar::pretty_percent(variable = ., n_decimal = 2), NA_real_)))
# A tibble: 4 × 7
  trauma_level seqic_1a lower_ci_1a upper_ci_1a seqic_1d lower_ci_1d upper_ci_1d
  <fct>        <chr>    <chr>       <chr>       <chr>    <chr>       <chr>      
1 I            100%     67.86%      100%        23.33%   10.64%      42.7%      
2 II           100%     56.09%      100%        29.17%   13.44%      51.25%     
3 III          <NA>     <NA>        <NA>        15%      3.96%       38.86%     
4 IV           <NA>     <NA>        <NA>        22.22%   7.37%       48.08%     

nemsqar: EMS QI with NEMSIS

  • Built on NEMSQA performance measures
  • Automatically detects and validates key elements
  • Scales to full state-level EMS datasets

nemsqar: Example Functions

nemsqar::adult_population(data)
nemsqar::trauma_population(data)
nemsqar::respiratory_01(data)
  • *_population() functions define eligible cases
  • Wrapper functions implement full NEMSQA measures

Real-world Impact

  • traumar: Risk-adjusted benchmarking + SEQIC indicators for all 120 trauma centers in Iowa
  • nemsqar1: First statewide report on all 21 NEMSQA measures in Iowa
  • Reproducible, interpretable, fast

Join us

  • Open source needs more voices!
  • Trauma, EMS, epidemiology - R users welcome!
  • Contributors:
    • Nicolas Foss, Iowa HHS
    • Samuel Kordik, Dallas Fire
    • Alyssa Green, ESO

Thank you!


Questions?

Contact

Nicolas Foss, Ed.D., MS
Epidemiologist
Bureau of Emergency Medical and Trauma Services
Bureau of Health Statistics
Division of Public Health
Iowa Department of Health and Human Services
e: nicolas.foss at hhs.iowa.gov
c: 515-985-9627
GitHub: bemts-hhs
slides: bemts-hhs/useR_2025